package com.drore.cloud.utils;

import com.drore.cloud.exception.ApiException;
import com.google.common.collect.Maps;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.InputStream;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/***
 * 浙江卓锐科技股份有限公司 版权所有@Copyright 2016
 * 说明  excel 工具类
 * @since:cloud-ims 1.0
 * @author <a href="mailto:baoec@drore.com">baoec@drore.com </a> 
 * 2017/09/15 11:43
 */

public class ImportExcelUtil {
    /**
     * 描述：获取IO流中的数据，组装成List<Map>对象
     * 此方法目前支持 sheet第一页导入
     * 如果表头字段需要校验 fields中把表头字段 传进来
     * totleIndex 总共有几行要导入 如果不确定 直接传0 或者headerIndex 相同的值
     * @param in,fileName
     * @return
     * @throws Exception
     */
    public static List<Map> getListByIndexExcel(InputStream in, String fileName, Map<String, String> fieldmap, Integer sheetIndex, Integer headerIndex, Integer firstIndex, Integer totleIndex) throws Exception {
        List<Map> list = new ArrayList<Map>();
        //由 fieldmap 得到key值的list
        List<String> fields = new ArrayList<String>(fieldmap.keySet());
        //准备一个 int 排序的map 里面存放着有序的 数据库表字段 如 name sex
        HashMap<Integer, String> int_map = new HashMap<Integer, String>();
        //创建Excel工作薄
        Workbook work = getWorkbook(in,fileName);
        if(null == work){
            throw new Exception("创建Excel工作薄为空！");
        }
        Sheet sheet = null;
        Row row = null;
        Cell cell = null;
        sheet = work.getSheetAt(sheetIndex);
        //遍历当前sheet中的所有行
        for (int j = headerIndex; j <= sheet.getLastRowNum(); j++) {
            row = sheet.getRow(j);
            if(row==null){continue;}
            //调试放开
//            if(j>39){
//                System.out.println(j);
//                System.out.println(row.getFirstCellNum());
//                System.out.println(row.getLastCellNum());
//                System.out.println(row.getFirstCellNum()==row.getLastCellNum()-1);
//            }

            if(getCellValue(row.getCell((row.getFirstCellNum()==row.getLastCellNum()-1)?row.getFirstCellNum():row.getFirstCellNum()+1))==""&&j>firstIndex){
                //循环到某一行为空时 结束

                System.out.println("循环到某一行为空时");
                break;
            }
            //遍历所有的列
            Map<String,Object> map=Maps.newLinkedHashMap();
            for (int y = row.getFirstCellNum(); y < row.getLastCellNum(); y++) {
                //第一行的所有列 表头验证
                String field=null;
                if(j!=totleIndex&&y<=fields.size()-1){
                    if(j==headerIndex){
                        field= row.getCell(y).getStringCellValue();
                            if(!fieldmap.get(fields.get(y)).equals(field)){
                                System.out.println(fieldmap.get(fields.get(y)));
                                System.out.println(field);
                                throw new ApiException("系统检测到您导入的excel文件中表头\""+field+"\"与系统表头\""+fields.get(y)+"\"没有对应，请检查后重试。");
                            }else {
                                int_map.put(y,fieldmap.get(fields.get(y)));
                            }
                        continue;
                    }
                    cell = row.getCell(y);
                    //调试时放开
//                    System.out.println( j+"--"+y);
//                    System.out.println(fields.get(y));
//                    if(j==39){
//                        System.out.println(cell);
//                        if(y==12){
//                            System.out.println(cell);
//                        }
//                    }
                    map.put(fields.get(y),(cell==null)?"":getCellValue(cell));
                }
            }
            if(map.size()>0){
                //map.put("report_date",report_date);
                list.add(map);
            }
        }
        work.close();
        return list;
    }

    /**
     * 描述：获取IO流中的数据，组装成List<Map>对象
     * 此方法目前支持 sheet第一页导入
     * 如果表头字段需要校验 fields中把表头字段 传进来
     * totleIndex 总共有几行要导入 如果不确定 直接传0 或者headerIndex 相同的值
     * @param in,fileName
     * @return
     * @throws Exception
     */
    public static List<Map> getListByNameExcel(InputStream in, String fileName, Map<String, String> fieldmap, String sheetName, Integer headerIndex, Integer firstIndex, Integer totleIndex) throws Exception {
        List<Map> list = new ArrayList<Map>();
        //由 fieldmap 得到key值的list
        List<String> fields = new ArrayList<String>(fieldmap.keySet());
        //准备一个 int 排序的map 里面存放着有序的 数据库表字段 如 name sex
        HashMap<Integer, String> int_map = new HashMap<Integer, String>();
        //创建Excel工作薄
        Workbook work = getWorkbook(in,fileName);
        if(null == work){
            throw new Exception("创建Excel工作薄为空！");
        }
        Sheet sheet = null;
        Row row = null;
        Cell cell = null;
        sheet = work.getSheet(sheetName);
        //遍历当前sheet中的所有行
        for (int j = headerIndex; j <= sheet.getLastRowNum(); j++) {
            row = sheet.getRow(j);
            if(row==null){continue;}
            //调试放开
//            if(j>39){
//                System.out.println(j);
//                System.out.println(row.getFirstCellNum());
//                System.out.println(row.getLastCellNum());
//                System.out.println(row.getFirstCellNum()==row.getLastCellNum()-1);
//            }

            if(getCellValue(row.getCell((row.getFirstCellNum()==row.getLastCellNum()-1)?row.getFirstCellNum():row.getFirstCellNum()+1))==""&&j>firstIndex){
                //循环到某一行为空时 结束

                System.out.println("循环到某一行为空时");
                break;
            }
            //遍历所有的列
            Map<String,Object> map=Maps.newLinkedHashMap();
            for (int y = row.getFirstCellNum(); y < row.getLastCellNum(); y++) {
                //第一行的所有列 表头验证
                String field=null;
                if(j!=totleIndex&&y<=fields.size()-1){
                    if(j==headerIndex){
                        field= row.getCell(y).getStringCellValue();
                        if(!fieldmap.get(fields.get(y)).equals(field)){
                            System.out.println(fieldmap.get(fields.get(y)));
                            System.out.println(field);
                            throw new ApiException("系统检测到您导入的excel文件中表头\""+field+"\"与系统表头\""+fields.get(y)+"\"没有对应，请检查后重试。");
                        }else {
                            int_map.put(y,fieldmap.get(fields.get(y)));
                        }
                        continue;
                    }
                    cell = row.getCell(y);
                    //调试时放开
//                    System.out.println( j+"--"+y);
//                    System.out.println(fields.get(y));
//                    if(j==39){
//                        System.out.println(cell);
//                        if(y==12){
//                            System.out.println(cell);
//                        }
//                    }
                    map.put(fields.get(y),(cell==null)?"":getCellValue(cell));
                }
            }
            if(map.size()>0){
                //map.put("report_date",report_date);
                list.add(map);
            }
        }
        work.close();
        return list;
    }


    /**
     * 描述：根据文件后缀，自适应上传文件的版本
     * @param inStr,fileName
     * @return
     * @throws Exception
     */
    public static   Workbook getWorkbook(InputStream inStr, String fileName) throws Exception {
        Workbook wb = null;
        if(fileName.endsWith("xls")){
            wb = new HSSFWorkbook(inStr);  //2003-
        }else if(fileName.endsWith("xlsx")){
            wb = new XSSFWorkbook(inStr);  //2007+
        }else{
            throw new Exception("解析的文件格式有误！");
        }
        return wb;
    }

    /**
     * 描述：对表格中数值进行格式化
     * @param cell
     * @return
     */
    public static Object getCellValue(Cell cell){
        Object value = null;
        DecimalFormat df = new DecimalFormat("0");  //格式化number String字符
        SimpleDateFormat sdf = new SimpleDateFormat("yyy-MM-dd");  //日期格式化
        DecimalFormat df2 = new DecimalFormat("0.00");  //格式化数字
        if(cell==null){
            return null;
        }
        switch (cell.getCellType()) {
            case Cell.CELL_TYPE_STRING:
                value = cell.getRichStringCellValue().getString();
                break;
            case Cell.CELL_TYPE_NUMERIC:
                if("General".equals(cell.getCellStyle().getDataFormatString())){
                    value = df.format(cell.getNumericCellValue());
                    //value = cell.getRichStringCellValue();
                }else if("m/d/yy".equals(cell.getCellStyle().getDataFormatString())){
                    value = sdf.format(cell.getDateCellValue());
                }else if("mmm-yy".equals(cell.getCellStyle().getDataFormatString())){
                    value = sdf.format(cell.getDateCellValue());
                }else{
                    //value = df2.format(cell.getNumericCellValue());
                    System.out.println("riqi   "+cell.getCellStyle().getDataFormatString());
                    value = cell.toString();
                }
                break;
            case Cell.CELL_TYPE_BOOLEAN:
                value = cell.getBooleanCellValue();
                break;
            case Cell.CELL_TYPE_BLANK:
                value = "";
                break;
            case Cell.CELL_TYPE_FORMULA:
                try {
                    value = String.valueOf(cell.getNumericCellValue());
                 } catch (IllegalStateException e) {
                     //value = String.valueOf(cell.getRichStringCellValue());
                    value=null;
                 }
                break;
            default:
                break;
        }
        return value;
    }

    /**
     * 描述：对表格中数值进行格式化
     * @param cell
     * @return
     */
    public static Object getCellValue2(Cell cell){
        Object value = null;
        DecimalFormat df = new DecimalFormat("0");  //格式化number String字符
        SimpleDateFormat sdf = new SimpleDateFormat("yyy-MM-dd");  //日期格式化
        DecimalFormat df2 = new DecimalFormat("0.00");  //格式化数字
        if(cell==null){
            return null;
        }
        switch (cell.getCellType()) {
            case Cell.CELL_TYPE_STRING:
                value = cell.getRichStringCellValue().getString();
                break;
            case Cell.CELL_TYPE_FORMULA:
                try {
                    value = String.valueOf(cell.getRichStringCellValue().getString());
                } catch (IllegalStateException e) {
                    //value = String.valueOf(cell.getRichStringCellValue());
                    value=null;
                }
                break;
            default:
                break;
        }
        return value;
    }

}
